package com.ruoyi.procurement.service.impl;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.BaseUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.procurement.domain.*;
import com.ruoyi.procurement.mapper.PsGoodsTypeMapper;
import com.ruoyi.procurement.mapper.PsOutboundMapper;
import com.ruoyi.procurement.mapper.PsProcureMapper;
import com.ruoyi.procurement.service.IPsGoodsService;
import com.ruoyi.procurement.service.IPsOutboundService;
import com.ruoyi.procurement.service.IPsProcureService;
import com.ruoyi.procurement.service.IPsReportingLossesService;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.cache.CacheKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import com.ruoyi.procurement.mapper.PsGoodsMapper;
import org.springframework.transaction.annotation.Transactional;

/**
 * 物品库存Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-10
 */
@Service
public class PsGoodsServiceImpl implements IPsGoodsService {
    @Autowired
    private PsGoodsMapper psGoodsMapper;
    @Autowired
    private PsGoodsTypeMapper psGoodsTypeMapper;
    @Autowired
    private IPsProcureService iPsProcureService;
    @Autowired
    private IPsReportingLossesService iPsReportingLossesService;
    @Autowired
    private IPsOutboundService iPsOutboundService;
    @Autowired
    private PsOutboundMapper psOutboundMapper;
    @Autowired
    private RedissonClient redissonClient;


    /**
     * 查询物品库存
     *
     * @param goodsId 物品库存主键
     * @return 物品库存
     */
    @Override
    public PsGoods selectPsGoodsByGoodsId(String goodsId) {
        return psGoodsMapper.selectPsGoodsByGoodsId(goodsId);
    }

    /**
     * 查询物品库存列表
     *
     * @param psGoods 物品库存
     * @return 物品库存
     */
    @Override
    public List<PsGoods> selectPsGoodsList(PsGoods psGoods) {
//        List<PsGoods> psGoods1 = psGoodsMapper.selectList(null);
//
//        HashMap<String, String> stringStringHashMap = new HashMap<>();
//        for (PsGoods goods : psGoods1) {
//
//            String nana = "";
//            QueryWrapper<PsGoods> psGoodsQueryWrapper = new QueryWrapper<>();
//            if (StringUtils.isNotEmpty(goods.getGoodsUnit())) {
//                psGoodsQueryWrapper.eq("goods_type_id",goods.getGoodsTypeId());
//                nana +=goods.getGoodsTypeId();
//            }
//            String goodsUnit = goods.getGoodsUnit();
//            if (StringUtils.isNotEmpty(goodsUnit)) {
//                psGoodsQueryWrapper.eq("goods_unit",goodsUnit);
//                nana +="-"+goodsUnit;
//            }
//            psGoodsQueryWrapper.ne("goods_id",goods.getGoodsId());
////            nana +="-"+goods.getGoodsId();
//            if (stringStringHashMap.containsKey(nana)) {
//                continue;
//            }
//            stringStringHashMap.put(nana,nana);
//
//            List<PsGoods> psGoods2 = psGoodsMapper.selectList(psGoodsQueryWrapper);
//            System.out.println(goods.getGoodsName());
//            if (goods.getGoodsName().equals("水面")) {
//                System.out.println(goods);
//            }
//            for (PsGoods psGoods3 : psGoods2) {
//                goods.setGoodsNum(goods.getGoodsNum().add(psGoods3.getGoodsNum()));
//                psGoodsMapper.deleteById(psGoods3.getGoodsId());
//
//                psGoodsMapper.updatePsGoods(goods);
//            }
//        }

        return psGoodsMapper.selectPsGoodsList(psGoods);
    }


    /**
     * 新增物品库存
     *
     * @param psGoods 物品库存
     * @return 结果
     */
    @Override
    public int insertPsGoods(PsGoods psGoods) {
        psGoods.setCreateTime(DateUtils.getNowDate());
        return psGoodsMapper.insert(psGoods);
    }

    /**
     * 修改物品库存
     *
     * @param psGoods 物品库存
     * @return 结果
     */
    @Override
    public int updatePsGoods(PsGoods psGoods) {
        psGoods.setUpdateTime(DateUtils.getNowDate());
        return psGoodsMapper.updateById(psGoods);
    }

    /**
     * 批量删除物品库存
     *
     * @param goodsIds 需要删除的物品库存主键
     * @return 结果
     */
    @Override
    public int deletePsGoodsByGoodsIds(String[] goodsIds) {
        for (String goodsId : goodsIds) {
            PsGoods psGoods = psGoodsMapper.selectById(goodsId);
            BigDecimal goodsNum = psGoods.getGoodsNum();
            if (goodsNum != null && goodsNum.doubleValue() > 0) {
                throw new ServiceException("删除失败！" + psGoods.getGoodsName() + " 库存不为空！");
            }
        }
//        for (String goodsId : goodsIds) {
//            //删除报损 采购 出库
//            //出库
//            iPsOutboundService.deleteByPsGoodsId(goodsId);
//            iPsReportingLossesService.deleteByPsGoodsId(goodsId);
//            iPsProcureService.deleteByPsGoodsId(goodsId);
//        }
        return psGoodsMapper.deleteById(goodsIds);
    }

    /**
     * 删除物品库存信息
     *
     * @param goodsId 物品库存主键
     * @return 结果
     */
    @Override
    public int deletePsGoodsByGoodsId(String goodsId) {
        PsGoods psGoods = psGoodsMapper.selectById(goodsId);
        BigDecimal goodsNum = psGoods.getGoodsNum();
        if (goodsNum != null && goodsNum.doubleValue() > 0) {
            throw new ServiceException("删除失败！" + psGoods.getGoodsName() + " 库存不为空！");
        }
        //删除报损 采购 出库
        //出库
        iPsOutboundService.deleteByPsGoodsId(goodsId);
        iPsReportingLossesService.deleteByPsGoodsId(goodsId);
        iPsProcureService.deleteByPsGoodsId(goodsId);

        return psGoodsMapper.deletePsGoodsByGoodsId(goodsId);
    }

    //psReportingLosses 报损记录 psProcure 采购记录 psOutbound出库记录
    @Override
    @Transactional
    public Boolean deduction(String PsGoodsTypeId, String type, PsReportingLosses psReportingLosses, PsProcure psProcure, PsOutbound psOutbound) {
        //获取一个锁的key
        RLock lock = redissonClient.getLock("lockname");
        try {
            if (lock.tryLock(30, TimeUnit.MINUTES)) {
                switch (type) {
                    case "采购": {
                        //查询库存是否存在 1.不存在 新增库存 2.存在 加库存
                        PsGoods psGoods = psGoodsMapper.selectByPsGoodsTypeId(PsGoodsTypeId, psProcure.getPsUnit());
                        if (psGoods != null) {
                            //追加库存 并且同步采购价格
                            if (psGoods.getGoodsPrice() == null) psGoods.setGoodsPrice(new BigDecimal("0.0"));
                            if (psGoods.getGoodsNum() == null) psGoods.setGoodsNum(new BigDecimal("0.0"));
                            //同步单价
//                        psGoods.setGoodsPrice(psGoods.getGoodsPrice().add(psProcure.getPsPrice()));
                            //追加库存
                            psGoods.setGoodsNum(psGoods.getGoodsNum().add(psProcure.getPsNum()));
                            psGoodsMapper.updateById(psGoods);
                            return true;
                        } else {
                            //不存在 则新增
                            psGoods = new PsGoods();
                            psGoods.setGoodsTypeId(psProcure.getPsGoodsTypeId());
                            PsGoodsType pp = psGoodsTypeMapper.selectById(psProcure.getPsGoodsTypeId());
                            psGoods.setGoodsName(pp.getPstName());
                            psGoods.setGoodsType(pp.getPstType());
                            psGoods.setGoodsNum(psProcure.getPsNum());
                            psGoods.setGoodsUnit(psProcure.getPsUnit());
                            psGoods.setGoodsUrl(psProcure.getPsUrl());
                            psGoods.setGoodsPrice(psProcure.getPsPrice());
                            psGoods.setGoodsDesc("无");
                            psGoodsMapper.insert(psGoods);
                            psProcure.setPsGoodsId(psGoods.getGoodsId());
                            iPsProcureService.updatePsProcure(psProcure);
                            return true;
                        }
                    }
                    case "出库": {
                        //1.查询库存是否存在 2.查询库存数量是否支持出库 支持(减库存) 不支持(提示用户)
                        PsGoods psGoods = psGoodsMapper.selectById(psOutbound.getPsGoodsId());
                        if (psGoods != null) {
                            //判断库存是否大于 需要出库的量
                            BigDecimal goodsNum = psGoods.getGoodsNum();
                            //出库数量
                            BigDecimal poNum = psOutbound.getPoNum();
                            if (goodsNum == null || goodsNum.doubleValue() <= 0 || poNum.doubleValue() > goodsNum.doubleValue()) {
                                throw new ServiceException("库存不足！");
                            }
                            //库存充足 减库存
                            psGoods.setGoodsNum(psGoods.getGoodsNum().subtract(poNum));
                            //同步出库单价
                            psGoods.setGoodsPrice(psOutbound.getPoPrice());
                            //报错库存剩余
                            psOutbound.setPoPriceRemaining(psGoods.getGoodsNum());

                            String goodsTypeId = psGoods.getGoodsTypeId();
                            PsGoodsType psGoodsType = psGoodsTypeMapper.selectById(goodsTypeId);
                            if (psGoodsType != null) {
                                psOutbound.setGoodsTypeId(goodsTypeId);
                                psOutbound.setGoodsType(psGoodsType.getPstType());
                                psOutbound.setPstSpecification(psGoodsType.getPstSpecification());
                            }

                            psGoodsMapper.updateById(psGoods);

                            //查询今天 条件 今天-同一个商品-同一个单位
                            List<PsOutbound> psOutbounds = iPsOutboundService.selectTodayPsOut(psOutbound.getPoDeliveryDate(), psOutbound.getPsGoodsId(), psOutbound.getPsUnitId());

                            if (CollUtil.isNotEmpty(psOutbounds)) {
                                BigDecimal bigDecimal = new BigDecimal("0.0");
                                for (PsOutbound outbound : psOutbounds) {
                                    if (outbound.getPoAmount() != null) {
                                        bigDecimal = bigDecimal.add(outbound.getPoNum());
                                    }
                                    psOutboundMapper.deletePsOutboundById(outbound.getId());
                                }
                                psOutbound.setPoNum(psOutbound.getPoNum().add(bigDecimal));
                            }
                            return true;
                        } else {
                            throw new ServiceException("出库失败！");
                        }
                    }
                    case "报损": {
                        //1.查询库存是否存在 2.查询库存数量是否支持报损操作
                        PsGoods psGoods = psGoodsMapper.selectById(psReportingLosses.getPsGoodsId());
                        BigDecimal goodsNum = psGoods.getGoodsNum();
                        if (psGoods != null) {
                            if (goodsNum == null || goodsNum.doubleValue() <= 0 || psReportingLosses.getPsGoodsNum().doubleValue() > goodsNum.doubleValue()) {
                                throw new ServiceException("报损库存不足！");
                            }
                            //库存充足 减库存
                            psGoods.setGoodsNum(psGoods.getGoodsNum().subtract(psReportingLosses.getPsGoodsNum()));

                            //报错库存剩余
                            psReportingLosses.setPsGoodsNumRemaining(psGoods.getGoodsNum());

                            psGoodsMapper.updateById(psGoods);
                            return true;
                        } else {
                            throw new ServiceException("报损失败！");
                        }
                    }
                    case "出库回退": {
                        PsGoods psGoods = selectPsGoodsByGoodsIdAnddelFlag(psOutbound.getPsGoodsId(), "0");
                        if (psGoods == null) {
                            throw new ServiceException("该商品已不存在！");
                        }
                        psGoods.setGoodsNum(psGoods.getGoodsNum().add(psOutbound.getPoNum()));
                        updatePsGoods(psGoods);
                        break;
                    }
                    case "采购回退": {
                        PsGoods psGoods = selectPsGoodsByGoodsIdAnddelFlag(psProcure.getPsGoodsId(), "0");
                        if (psGoods == null) {
                            throw new ServiceException("该商品已不存在！");
                        }
                        //判断库存是否支持回退
                        BigDecimal psNum = psProcure.getPsNum();
                        BigDecimal goodsNum = psGoods.getGoodsNum();
                        if (psNum.compareTo(goodsNum) <= 0) {
                            //减库存
                            psGoods.setGoodsNum(psGoods.getGoodsNum().subtract(psNum));
                            updatePsGoods(psGoods);
                        } else {
                            throw new ServiceException("采购回退失败！库存不足！");
                        }
                        break;
                    }
                    case "报损回退": {
                        PsGoods psGoods = selectPsGoodsByGoodsIdAnddelFlag(psReportingLosses.getPsGoodsId(), "0");
                        if (psGoods == null) {
                            throw new ServiceException("该商品已不存在！");
                        }
                        psGoods.setGoodsNum(psGoods.getGoodsNum().add(psReportingLosses.getPsGoodsNum()));
                        updatePsGoods(psGoods);
                        break;
                    }
                }
            } else {
                throw new ServiceException("操作失败！");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //进行释放锁
            lock.unlock();
        }
        return false;
    }

    @Override
    public PsGoods selectPsGoodsByGoodsIdAnddelFlag(String psGoodsId, String delFlag) {
        PsGoods psGoods = psGoodsMapper.selectPsGoodsByGoodsIdAnddelFlag(psGoodsId, delFlag);
        return psGoods;
    }
}
